# wirte by hasaki
# first edit on 2019/01/11
# last change on 2019/07/20
# hasaki 小策略模板
import requests
import json
from datetime import datetime,timedelta
from hashakisea.engine.log.logSystem import Ding

class HaStrategy:
    def __init__(self):
        self.Ding=Ding()
        self.orderDict={}                     # 用于保存下单数据的字典
        self.cancelList=[]                    # 撤单列表
        self.pos=0                            # 策略持仓
        self.capital=0                        # 策略总资产
        self.account_pos=0                    # 
        self.history_bars=None                # 历史行情的K线数据

        self.hour_bar_list=[]                 # 小时线数据保存列表
        self.last_time=None                   # 上一次更新的时间
        self.is_update=False                  # 是否到了更新数据的时候
        self.counter_of_hour_bar=0            # 小时线的个数

        self.bar_of_4h=None                   # 最新4小时的K线
        

    # ----------------------------------------------------------------------------------
    # 需要用户去编写的函数
    def next(self,data):
        '''策略模块的入口，接收引擎推送过来的数据，被动触发执行策略文件，data可以为tick,bar,depth没有限定'''
        raise NotImplementedError
    
    def onOrder(self):
        '''当下单行为触发时被动执行的函数'''
        print('触发下单')
    
    def onTrade(self):
        '''当成交时触发的被动执行函数'''
        pass
    
    def onBar_4h(self,data):
        pass

    # ----------------------------------------------------------------------------------
    # 辅助编写策略的模块
    def buy(self,target_symbol,price,volume):
        '''下单买功能'''
        self.onOrder()
        self.orderDict.clear()
        self.orderDict['side']='buy'
        self.orderDict['target_symbol']=target_symbol
        self.orderDict['price']=price
        self.orderDict['volume']=volume
    
    def sell(self,target_symbol,price,volume):
        '''下单卖功能'''
        self.onOrder()
        self.orderDict.clear()
        self.orderDict['side']='sell'
        self.orderDict['target_symbol']=target_symbol
        self.orderDict['price']=price
        self.orderDict['volume']=volume
    
    def cancelOrder(self,orderID=None):
        '''撤单，当orderID为空的时候，全部撤单'''
        self.onOrder()
        if orderID:
            self.cancelList.append(orderID)
        else:
            # TODO : 全部撤单实现
            pass
    
    def returnOrder(self):
        '''返回一个下单字典给引擎,策略模块的出口'''
        return self.orderDict
    
    def getHistory(self):
        '''获取当前时间的前N个历史数据'''
        return self.history_bars
    
    def ding(self,webhost,string):
        '''发送消息到钉钉群'''
        self.Ding.setting(webhost)
        header={"Content-Type":"application/json ;charset=utf-8"}
        #msg={"msgtype":"text","text":{"content":string},"at":{"isAtAll":1}}
        msg={"msgtype":"text","text":{"content":string}}   # 这个不会@所有人
        msg_str=json.dumps(msg)
        res=requests.post(webhost,data=msg_str,headers=header)
        print(res.text)
    
    def pic_ding(self,pic_url,title):
        '''向钉钉群发送图片,第一个参数是图片的地址，第二个参数是图片的标题'''
        self.Ding.send_pic(pic_url,title)
        
    # ------------------------------------------------------------------
    # 我自己的特色功能函数
    # 1,更新大周期K线的模板看uppdateBarStrategy.py
    def getHourPriceChange(self):
        '''计算一个小时内，成交曲线的开始值与结束值的连线的斜率'''
        pass

    def calculateSidePower(self):
        '''调用这个函数，next推送的必须是深度数据，比较买卖双方的能量'''
        pass
    
    def checkSideEat(self):
        '''调用这个函数，next推送的必须是深度数据，有时候买卖双方的挂单量并不能代表能量，因为有很多用户是发停止单的'''
        pass
    
    def getAccountCash(self):
        '''获取账户现金'''
        pass
    
    def getAccountPos(self):
        '''获取账户持仓'''
        pass
    
    def make1hBar(self):
        '''生成一小时的k线'''
        pass
    
    def make1dBar(self):
        '''生成一天的K线'''
        pass
    
    def update_4h_bar(self,bar):
        '''生成4小时的线'''
        self.counter_of_hour_bar+=1

        self.hour_bar_list.append(bar)
        big_bar={}
        # 更新成更大周期的K线
        if self.is_update:
            big_bar['time']=bar['time']
            big_bar['open']=self.hour_bar_list[0]['open']
            big_bar['close']=bar['close']
            big_bar['high']=max([i['high'] for i in self.hour_bar_list])
            big_bar['low']=min([j['low'] for j in self.hour_bar_list])

            # 先求所有成交量的总和再除以小时线的条数，即求出平均一小时的成交量，最后乘以4，得出4小时的平均成交量
            big_bar['volume']= 4 * sum([k['volume'] for k in self.hour_bar_list]) / self.counter_of_hour_bar

            self.bar_of_4h=big_bar
            self.onBar_4h(self.bar_of_4h)

            # 合成好了大周期的K线后接下来就是收尾工作
            self.is_update=False
            self.counter_of_hour_bar=0
            self.hour_bar_list.clear()
    
    def transerTime(self,data):
        '''时间大小比较'''
        if not self.last_time:
            self.last_time=datetime.strptime(data['time'],'%Y-%m-%d %H:%M:%S')

        elif self.last_time+timedelta(hours=4)<=datetime.strptime(data['time'],'%Y-%m-%d %H:%M:%S'):
            print('更新K线',data['time'])
            self.last_time=datetime.strptime(data['time'],'%Y-%m-%d %H:%M:%S')
            self.is_update=True